﻿using Newtonsoft.Json;
using Formatting = Newtonsoft.Json.Formatting;

namespace HVACWebService.Common

{
    public class JsonSerializer
    {
        /// <summary>
        /// Sole instance of this class.
        /// </summary>
        private static readonly JsonSerializer _instance = new JsonSerializer();

        /// <summary>
        /// Prevents a default instance of the <see cref="JsonSerializer"/> class from being created. 
        /// No public constructor should be available
        /// </summary>
        private JsonSerializer()
        {
            //Serializer = new JavaScriptSerializer();
            //Serializer.RegisterConverters(new List<JavaScriptConverter> { new DateTimeConverter() });
        }

        /// <summary>
        /// Retrieves the sole instance of this class.
        /// </summary>
        public static JsonSerializer Instance
        {
            get
            {
                return _instance;
            }
        }

        public string Serialize(object value)
        {
            return Serialize(value, false);
        }

        /// <summary>
        /// Serializes the specified the object.
        /// </summary>
        /// <param name="value">The object.</param>
        /// <param name="indent">indent formatting</param>
        /// <returns></returns>
        public string Serialize(object value, bool indent)
        {
            var result = JsonConvert.SerializeObject(
                value, indent ? Formatting.Indented : Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });

            return result;
        }

        /// <summary>
        /// Serializes the specified object for use in JavaScript blocks. This is done by
        /// adding a commented out CDATA block around the output so it can both contain
        /// special characters and still be XHTML1.0 valid.
        /// </summary>
        /// <example>A smiple object would look like this: <c>/* &lt;![CDATA[ */ {"property":"value"} /* ]]&gt; */</c></example>
        /// <param name="value">The object to serialize.</param>
        /// <returns></returns>
        public string SerializeForJavaScript(object value)
        {
            return string.Format(@"/*<![CDATA[*/ {0} /*]]>*/", this.Serialize(value));
        }

        /// <summary>
        /// Deserialize a json string to an object based on the object's class name, not the full qualified name
        /// </summary>
        /// <typeparam name="T">expected type</typeparam>
        /// <param name="serializedObject">json string</param>
        /// <returns></returns>        
        public T Deserialize<T>(string serializedObject)
        {
            //return Serializer.Deserialize<T>(serializedObject);
            var deserialized = JsonConvert.DeserializeObject<T>(serializedObject);
            return deserialized;
        }
    }
}
